package com.datapermission.interceptor;

import com.baomidou.mybatisplus.extension.plugins.handler.MultiDataPermissionHandler;
import com.datapermission.annotation.Permission;
import com.datapermission.aspect.PermissionContext;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.expression.operators.relational.ItemsList;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
public class MyDataPermissionHandler implements MultiDataPermissionHandler {

    @Override
    public Expression getSqlSegment(Table table, Expression where, String mappedStatementId) {
        Permission permission = PermissionContext.get();
        if (permission == null) {
            log.info("权限注解为空,不处理该sql");
            return null;
        }
        // 如果手动把表的名称和别名都置空了,就不设置权限
        String permissionTableName = permission.tableName();
        if (StringUtils.isBlank(permissionTableName)) {
            return null;
        }
        // 获取当前SQL的表名,优先获取别名,如果别名没有,就获取表名
        Alias alias = table.getAlias();
        String processTableName = alias == null ? table.getName() : alias.getName();
        // 如果不相等,代表不是要操作的表,直接返回
        if (!StringUtils.equalsIgnoreCase(processTableName, permissionTableName)) {
            return null;
        }
        log.info("当前匹配到的表名为: 【{}】", permissionTableName);
        List<Long> deptIds = getUserPermissionDeptIds();
        if (CollectionUtils.isEmpty(deptIds)) {
            log.info("当前用户无数据权限");
            return getEmptyDataExpression(permissionTableName);
        }
        ItemsList itemList = new ExpressionList(deptIds.stream().map(LongValue::new).collect(Collectors.toList()));
        String columnName = permissionTableName + "." + permission.deptIdFieldName();
        return new InExpression(new Column(columnName), itemList);
    }

    /**
     * 模拟获取当前登录用户的数据权限信息
     *
     * @return 当前登录用户的数据权限信息
     */
    private List<Long> getUserPermissionDeptIds() {
        return Arrays.asList(111L, 222L, 333L, 444L, 555L);
    }

    /**
     * 构造 id = -1L,过滤所有数据
     *
     * @param permissionTableName 表名
     * @return 无权限的表达式
     */
    private Expression getEmptyDataExpression(String permissionTableName) {
        // table.id = -1L,always empty data
        Column column = new Column(permissionTableName + ".id");
        LongValue value = new LongValue(-1L);
        EqualsTo equalsTo = new EqualsTo();
        equalsTo.setLeftExpression(column);
        equalsTo.setRightExpression(value);
        return equalsTo;
    }
}